package gee

import (
	"encoding/json"
	"fmt"
	"net/http"
)

/*
HTTP一个完整的响应包括消息头（header）和消息体（body），header包含了状态码（StatusCode）和消息类型（ContentType）
此文件的设计目的是封装请求和响应请求两个类型，以及框架的一些额外的功能
*/

type H map[string]interface{} //关系映像表的别名

type Context struct {
	Writer     http.ResponseWriter //响应请求
	Req        *http.Request       //请求
	Path       string              //路径
	Method     string              //方法
	StatusCode int                 //定义状态码
}

func newContext(w http.ResponseWriter, req *http.Request) *Context { //将请求和响应请求封装起来
	return &Context{
		Writer: w,
		Req:    req,
		Path:   req.URL.Path,
		Method: req.Method,
	}
}

func (c *Context) PostForm(key string) string { //最后面的那个string是返回值
	return c.Req.FormValue(key)
}

func (c *Context) Query(key string) string {
	return c.Req.URL.Query().Get(key)
}

func (c *Context) Statues(code int) { //状态函数，函数参数为状态
	c.StatusCode = code
	c.Writer.WriteHeader(code)
}

func (c *Context) SetHeader(key string, value string) { //设置消息头
	c.Writer.Header().Set(key, value)
}

func (c *Context) String(code int, format string, values ...interface{}) {
	c.SetHeader("Content", "text/plain")
	c.Statues(code)
	c.Writer.Write([]byte(fmt.Sprintf(format, values...)))
}

func (c *Context) Json(code int, obj interface{}) {
	c.SetHeader("Content-Type", "application/json") //设置消息头
	c.Statues(code)                                 //状态码
	encoder := json.NewEncoder(c.Writer)            //:=的作用是无需声明变量类型
	if err := encoder.Encode(obj); err != nil {     //请求编码
		http.Error(c.Writer, err.Error(), 500)
	}
}

func (c *Context) Data(code int, data []byte) {
	c.Statues(code)
	c.Writer.Write(data)
}

func (c *Context) HTML(code int, html string) {
	c.SetHeader("Content-Type", "text/html")
	c.Statues(code)
	c.Writer.Write([]byte(html))
}
